from sqlalchemy.orm import Session
from app.db.model import User
from app.api.schemas.user import UserDataBase, UserBase
from passlib.context import CryptContext
from typing import Optional, Dict, List

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


# 注册新用户，返回成功信息
def register_user(db: Session, user: UserDataBase) -> Dict:
    user.passWord = get_password_hash(user.passWord)
    registerUser = User(**user.dict())
    db.add(registerUser)
    db.commit()
    return db.query(User).all()


# 通过用户名查询用户，返回用户信息(密码不返回)
def get_user(db: Session, userName: Optional[str] = None) -> List:
    """
    根据用户名查询用户
    :param db: 数据库session
    :param user: 查询用户信息
    :return: 查询到的用户
    """
    if userName == "":
        return db.query(User).all()
    else:
        return db.query(User).filter_by(userName=userName).all()

# 通过用户名删除用户
def del_user(db: Session, userName: str):
    db.query(User).filter_by(userName=userName).delete()
    db.commit()
    return db.query(User).all()

# 通过用户名更新用户
def update_user(db: Session, user: UserBase):
    res = db.query(User).filter_by(userName=user.userName).first()
    for key in user.dict():
        setattr(res, key, getattr(user, key))

    # res.name = user.name
    # res.apartment = user.apartment
    # res.authority = user.authority
    db.commit()
    return db.query(User).all()


# 获得hash密码
def get_password_hash(password):
    """
    哈希来自用户的密码
    :param password: 原密码
    :return: 哈希后的密码
    """
    return pwd_context.hash(password)


# 校验密码
def verify_password(plain_password, hashed_password):
    """
    校验接收的密码是否与存储的哈希值匹配
    :param plain_password: 原密码
    :param hashed_password: 哈希后的密码
    :return: 返回值为bool类型，校验成功返回True,反之False
    """
    return pwd_context.verify(plain_password, hashed_password)


# 校验用户
def check_user(db: Session, login_user):
    """
    校验用户
    :param login_user: 登录用户，schemas为class UserInfo
    :return: user -> List
    """
    user = get_user(db, login_user.userName)[0]
    if user and verify_password(login_user.passWord, user.passWord):
        return user
    else:
        return None
